home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
ip
/
ka9q
/
alpha.arc
/
NRCMD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-07-26
|
13KB
|
588 lines
/* net/rom user command processing
* Dan Frank, W9NK
*/
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "netrom.h"
#include "timer.h"
#include "iface.h"
#include "lapb.h"
#include "cmdparse.h"
#include <ctype.h>
static int dointerface(), dobcnodes(), donodetimer(), donrroute(),
doobsotimer(), donodefilter() ;
static struct cmds nrcmds[] = {
"bcnodes", dobcnodes, 2, "netrom bcnodes <interface>", NULLCHAR,
"interface", dointerface, 4,
"netrom interface <interface> <alias> <quality>", NULLCHAR,
"nodefilter", donodefilter, 0, NULLCHAR, NULLCHAR,
"nodetimer", donodetimer, 0, NULLCHAR, NULLCHAR,
"obsotimer", doobsotimer, 0, NULLCHAR, NULLCHAR,
"route", donrroute, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0,
"netrom subcommands: bcnodes interface nodetimer nodefilter obsotimer route",
NULLCHAR
} ;
static struct timer nodetimer ; /* timer for nodes broadcasts */
static struct timer obsotimer ; /* timer for aging routes */
/* Command multiplexer */
donetrom(argc,argv)
int argc ;
char *argv[] ;
{
return subcmd(nrcmds,argc,argv) ;
}
static int dorouteadd(), doroutedrop(), doroutedump(), dorouteinfo() ;
static struct cmds routecmds[] = {
"add", dorouteadd, 6,
"netrom route add <alias> <destination> <interface> <quality> <neighbor>",
"add failed",
"drop", doroutedrop, 4,
"netrom route drop <destination> <neighbor> <interface>",
"drop failed",
"info", dorouteinfo, 2,
"netrom route info <destination>", NULLCHAR,
NULLCHAR, NULLFP, 0,
"netrom route subcommands: add drop info",
NULLCHAR
} ;
/* Route command multiplexer */
static
donrroute(argc, argv)
int argc ;
char *argv[] ;
{
if (argc < 2) {
doroutedump() ;
return 0 ;
}
return subcmd(routecmds,argc,argv) ;
}
/* Dump a list of known routes */
static
doroutedump()
{
register struct nrroute_tab *rp ;
register int i, column ;
char buf[16] ;
char *cp ;
column = 1 ;
for (i = 0 ; i < NRNUMCHAINS ; i++)
for (rp = nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rp->next) {
strcpy(buf,rp->alias) ;
/* remove trailing spaces */
if ((cp = index(buf,' ')) == NULLCHAR)
cp = &buf[strlen(buf)] ;
if (cp != buf) /* don't include colon for null alias */
*cp++ = ':' ;
pax25(cp,&rp->call) ;
printf("%-16s ",buf) ;
if (column++ == 4) {
printf("\n") ;
column = 1 ;
}
}
if (column != 1)
printf("\n") ;
return 0 ;
}
/* print detailed information on an individual route */
dorouteinfo(argc,argv)
int argc ;
char *argv[] ;
{
register struct nrroute_tab *rp ;
register struct nr_bind *bp ;
register struct nrnbr_tab *np ;
struct ax25_addr dest ;
char neighbor[60] ;
if (setcall(&dest,argv[1]) == -1) {
printf ("bad destination name\n") ;
return -1 ;
}
if ((rp = find_nrroute(&dest)) == NULLNRRTAB) {
printf("no such route\n") ;
return -1 ;
}
for (bp = rp->routes ; bp != NULLNRBIND ; bp = bp->next) {
np = bp->via ;
psax25(neighbor,np->call) ;
printf("%1s %3d %3d %-8s %s\n",
(bp->flags & NRB_PERMANENT ? "P" : " "),
bp->quality,bp->obsocnt,
nrifaces[np->interface].interface->name,
neighbor) ;
}
return 0 ;
}
/* convert a null-terminated alias name to a blank-filled, upcased */
/* version. Return -1 on failure. */
static int
putalias(to,from)
register char *to, *from ;
{
int len, i ;
if ((len = strlen(from)) > ALEN) {
printf ("alias too long - six characters max\n") ;
return -1 ;
}
for (i = 0 ; i < ALEN ; i++) {
if (i < len) {
if (islower(*from))
*to++ = toupper(*from++) ;
else
*to++ = *from++ ;
}
else
*to++ = ' ' ;
}
*to = '\0' ;
return 0 ;
}
/* Add a route */
dorouteadd(argc, argv)
int argc ;
char *argv[] ;
{
char alias[7] ;
struct ax25_addr dest ;
unsigned quality ;
char neighbor[AXALEN * 3] ;
register int i ;
int naddr ;
/* format alias (putalias prints error message if necessary) */
if (putalias(alias,argv[1]) == -1)
return -1 ;
/* format destination callsign */
if (setcall(&dest,argv[2]) == -1) {
printf("bad destination callsign\n") ;
return -1 ;
}
/* find interface */
for (i = 0 ; i < nr_numiface ; i++)
if (!strcmp(nrifaces[i].interface->name,argv[3]))
break ;
if (i == nr_numiface) {
printf("Interface \"%s\" not found\n",argv[3]) ;
return -1 ;
}
/* get and check quality value */
if ((quality = atoi(argv[4])) > 255) {
printf("maximum route quality is 255\n") ;
return -1 ;
}
/* make sure no more than 2 digis */
naddr = argc - 5 ;
if (naddr > 3) {
printf("no more than 2 digipeaters for a net/rom neighbor\n") ;
return -1 ;
}
/* format neighbor address string */
setpath(neighbor,&argv[5],naddr) ;
return nr_routeadd(alias,&dest,i,quality,neighbor,1) ;
}
/* drop a route */
static
doroutedrop(argc,argv)
int argc ;
char *argv[] ;
{
struct ax25_addr dest, neighbor ;
register int i ;
/* format destination and neighbor callsigns */
if (setcall(&dest,argv[1]) == -1) {
printf("bad destination callsign\n") ;
return -1 ;
}
if (setcall(&neighbor,argv[2]) == -1) {
printf("bad neighbor callsign\n") ;
return -1 ;
}
/* find interface */
for (i = 0 ; i < nr_numiface ; i++)
if (!strcmp(nrifaces[i].interface->name,argv[3]))
break ;
if (i == nr_numiface) {
printf("Interface \"%s\" not found\n",argv[3]) ;
return -1 ;
}
return nr_routedrop(&dest,&neighbor,i) ;
}
/* make an interface available to net/rom */
int
dointerface(argc,argv)
int argc ;
char *argv[] ;
{
register char *sp, *dp ;
int i, len ;
register struct interface *ifp ;
extern struct interface *ifaces ;
if (nr_interface == NULLIF) {
printf("Attach netrom interface first\n") ;
return 1 ;
}
if (nr_numiface >= NRNUMIFACE) {
printf("Only %d net/rom interfaces available\n",NRNUMIFACE) ;
return 1 ;
}
for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
if(strcmp(argv[1],ifp->name) == 0)
break;
}
if(ifp == NULLIF){
printf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
for (i = 0 ; i < nr_numiface ; i++)
if (nrifaces[i].interface == ifp) {
printf("Interface \"%s\" is already registered\n",argv[1]) ;
return 1 ;
}
nrifaces[nr_numiface].interface = ifp ;
if (putalias(nrifaces[nr_numiface].alias,argv[2]) == -1)
return 1 ;
if ((nrifaces[nr_numiface].quality = atoi(argv[3])) > 255) {
printf("Quality cannot be greater than 255\n") ;
return 1 ;
}
nr_numiface++ ; /* accept this interface */
return 0 ;
}
/* Broadcast nodes list on named interface. */
int
dobcnodes(argc,argv)
int argc ;
char *argv[] ;
{
register int i ;
for (i = 0 ; i < nr_numiface ; i++)
if (!strcmp(nrifaces[i].interface->name,argv[1]))
break ;
if (i == nr_numiface) {
printf("Interface \"%s\" not found\n",argv[1]) ;
return 1 ;
}
nr_bcnodes(i) ;
}
#define TICKSPERSEC (1000 / MSPTICK) /* Ticks per second */
/* Set outbound node broadcast interval */
static int
donodetimer(argc,argv)
int argc;
char *argv[];
{
int donodetick();
if(argc < 2){
printf("%d/%d\n",(nodetimer.start - nodetimer.count)/TICKSPERSEC,
nodetimer.start/TICKSPERSEC);
return 0;
}
stop_timer(&nodetimer) ; /* in case it's already running */
nodetimer.func = (void (*)())donodetick;/* what to call on timeout */
nodetimer.arg = NULLCHAR; /* dummy value */
nodetimer.start = atoi(argv[1])*TICKSPERSEC; /* set timer duration */
start_timer(&nodetimer); /* and fire it up */
return 0;
}
static int
donodetick()
{
register int i ;
for (i = 0 ; i < nr_numiface ; i++)
nr_bcnodes(i) ;
/* Restart timer */
start_timer(&nodetimer) ;
}
/* Set timer for aging routes */
static int
doobsotimer(argc,argv)
int argc;
char *argv[];
{
extern int doobsotick();
if(argc < 2){
printf("%d/%d\n",(obsotimer.start - obsotimer.count)/TICKSPERSEC,
obsotimer.start/TICKSPERSEC);
return 0;
}
stop_timer(&obsotimer) ; /* just in case it's already running */
obsotimer.func = (void (*)())doobsotick;/* what to call on timeout */
obsotimer.arg = NULLCHAR; /* dummy value */
obsotimer.start = atoi(argv[1])*TICKSPERSEC; /* set timer duration */
start_timer(&obsotimer); /* and fire it up */
return 0;
}
/* Go through the routing table, reducing the obsolescence count of
* non-permanent routes, and purging them if the count reaches 0
*/
static int
doobsotick()
{
register struct nrnbr_tab *np ;
register struct nrroute_tab *rp, *rpnext ;
register struct nr_bind *bp, *bpnext ;
struct ax25_addr neighbor ;
int i ;
for (i = 0 ; i < NRNUMCHAINS ; i++) {
for (rp = nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rpnext) {
rpnext = rp->next ; /* save in case we free this route */
for (bp = rp->routes ; bp != NULLNRBIND ; bp = bpnext) {
bpnext = bp->next ; /* in case we free this binding */
if (bp->flags & NRB_PERMANENT) /* don't age these */
continue ;
if (--bp->obsocnt == 0) { /* time's up! */
if (bp->next != NULLNRBIND)
bp->next->prev = bp->prev ;
if (bp->prev != NULLNRBIND)
bp->prev->next = bp->next ;
else
rp->routes = bp->next ;
rp->num_routes-- ; /* one less binding */
np = bp->via ; /* find the neighbor */
free(bp) ; /* now we can free the bind */
/* Check to see if we can free the neighbor */
if (--np->refcnt == 0) {
if (np->next != NULLNTAB)
np->next->prev = np->prev ;
if (np->prev != NULLNTAB)
np->prev->next = np->next ;
else {
memcpy(neighbor.call,np->call,ALEN) ;
neighbor.ssid = np->call[ALEN] ;
nrnbr_tab[nrhash(&neighbor)] = np->next ;
}
free(np) ; /* free the storage */
}
}
}
if (rp->num_routes == 0) { /* did we free them all? */
if (rp->next != NULLNRRTAB)
rp->next->prev = rp->prev ;
if (rp->prev != NULLNRRTAB)
rp->prev->next = rp->next ;
else
nrroute_tab[i] = rp->next ;
free(rp) ;
}
}
}
start_timer(&obsotimer) ;
}
static int donfadd(), donfdrop(), donfmode() ;
static struct cmds nfcmds[] = {
"add", donfadd, 3,
"netrom nodefilter add <neighbor> <interface>",
"add failed",
"drop", donfdrop, 3,
"netrom nodefilter drop <neighbor> <interface>",
"drop failed",
"mode", donfmode, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0,
"nodefilter subcommands: add drop mode",
NULLCHAR
} ;
/* nodefilter command multiplexer */
static
donodefilter(argc,argv)
int argc ;
char *argv[] ;
{
if (argc < 2) {
donfdump() ;
return 0 ;
}
return subcmd(nfcmds,argc,argv) ;
}
/* display a list of <callsign,interface> pairs from the filter
* list.
*/
static
donfdump()
{
int i, column = 1 ;
struct nrnf_tab *fp ;
char buf[16] ;
for (i = 0 ; i < NRNUMCHAINS ; i++)
for (fp = nrnf_tab[i] ; fp != NULLNRNFTAB ; fp = fp->next) {
pax25(buf,&fp->neighbor) ;
printf("%-7s %-8s ",
buf,nrifaces[fp->interface].interface->name) ;
if (column++ == 4) {
printf("\n") ;
column = 1 ;
}
}
if (column != 1)
printf("\n") ;
return 0 ;
}
/* add an entry to the filter table */
static
donfadd(argc,argv)
int argc ;
char *argv[] ;
{
struct ax25_addr neighbor ;
register int i ;
/* format callsign */
if (setcall(&neighbor,argv[1]) == -1) {
printf("bad neighbor callsign\n") ;
return -1 ;
}
/* find interface */
for (i = 0 ; i < nr_numiface ; i++)
if (!strcmp(nrifaces[i].interface->name,argv[2]))
break ;
if (i == nr_numiface) {
printf("Interface \"%s\" not found\n",argv[2]) ;
return -1 ;
}
return nr_nfadd(&neighbor,i) ;
}
/* drop an entry from the filter table */
static
donfdrop(argc,argv)
int argc ;
char *argv[] ;
{
struct ax25_addr neighbor ;
register int i ;
/* format neighbor callsign */
if (setcall(&neighbor,argv[1]) == -1) {
printf("bad neighbor callsign\n") ;
return -1 ;
}
/* find interface */
for (i = 0 ; i < nr_numiface ; i++)
if (!strcmp(nrifaces[i].interface->name,argv[2]))
break ;
if (i == nr_numiface) {
printf("Interface \"%s\" not found\n",argv[2]) ;
return -1 ;
}
return nr_nfdrop(&neighbor,i) ;
}
/* nodefilter mode subcommand */
static
donfmode(argc,argv)
int argc ;
char *argv[] ;
{
if (argc < 2) {
printf("filter mode is ") ;
switch (nr_nfmode) {
case NRNF_NOFILTER:
printf("none\n") ;
break ;
case NRNF_ACCEPT:
printf("accept\n") ;
break ;
case NRNF_REJECT:
printf("reject\n") ;
break ;
default:
printf("some strange, unknown value\n") ;
}
return 0 ;
}
switch (argv[1][0]) {
case 'n':
case 'N':
nr_nfmode = NRNF_NOFILTER ;
break ;
case 'a':
case 'A':
nr_nfmode = NRNF_ACCEPT ;
break ;
case 'r':
case 'R':
nr_nfmode = NRNF_REJECT ;
break ;
default:
printf("modes are: none accept reject\n") ;
return -1 ;
}
return 0 ;
}